package com.jeesit.cloud.spot.web.jwt;

import com.jeesit.cloud.feign.IUserFeign;
import com.jeesit.cloud.verify.UserAuthDetail;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
@Slf4j
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter{
    @Resource
    private IUserFeign userFeign;
    @Resource
    private JwtTokenUtil jwtTokenUtil;

    @Override
    protected void doFilterInternal(HttpServletRequest httpRequest, HttpServletResponse httpResopnse, FilterChain filterChain) throws ServletException, IOException {
        if ("OPTIONS".equalsIgnoreCase(httpRequest.getMethod())) {
            httpResopnse.setStatus(HttpServletResponse.SC_OK);
        } else {
            String authToken = httpRequest.getHeader(jwtTokenUtil.getHeader());
            if (authToken != null) {
                String username = jwtTokenUtil.getUsernameFromToken(authToken);
                if (username != null) {
                    UserAuthDetail userDetails = userFeign.getUserDetails(username);
                    if (userDetails != null && jwtTokenUtil.validateToken(authToken, userDetails)) {
                        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword(), userDetails.getAuthorities());
                        authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpRequest));
                        SecurityContextHolder.getContext().setAuthentication(authentication);
                    }
                }
            }
            filterChain.doFilter(httpRequest, httpResopnse);
        }
    }
}
